﻿using CommunityToolkit.Mvvm.Input;
using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
using Notifications.Wpf;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
using System.Windows.Input;
using VideoTools.Util;
using VideoTools.vo;

namespace VideoTools.Commands
{
    public class AjustTimelineCommands : NotifyPropertyBase
    {
        private static volatile AjustTimelineCommands _instance;
        private static readonly object SyncRoot = new object();

        public static AjustTimelineCommands Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (SyncRoot)
                    {
                        if (_instance == null)
                        {
                            _instance = new AjustTimelineCommands();
                        }
                    }
                }

                return _instance;
            }
        }

        private AjustTimelineCommands()
        {
            System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
        }

        private ObservableCollection<string> _FileList = new ObservableCollection<string>();

        public ObservableCollection<string> FileList
        {
            get => _FileList;
            set => SetProperty(ref _FileList, value);
        }

        private ObservableCollection<Subtitle> _SubtitleList = new ObservableCollection<Subtitle>();

        public ObservableCollection<Subtitle> SubtitleList
        {
            get => _SubtitleList;
            set => SetProperty(ref _SubtitleList, value);
        }

        private bool _TradToSimple = true;

        public bool TradToSimple
        {
            get => _TradToSimple;
            set => SetProperty(ref _TradToSimple, value);
        }

        private bool _AjustOneEnable = false;

        public bool AjustOneEnable
        {
            get => _AjustOneEnable;
            set => SetProperty(ref _AjustOneEnable, value);
        }

        private bool _AjustAllEnable = true;

        public bool AjustAllEnable
        {
            get => _AjustAllEnable;
            set => SetProperty(ref _AjustAllEnable, value);
        }

        private bool _ClearListEnable = true;

        public bool ClearListEnable
        {
            get => _ClearListEnable;
            set => SetProperty(ref _ClearListEnable, value);
        }

        private string _TimeLeave;

        public string TimeLeave
        {
            get => _TimeLeave;
            set => SetProperty(ref _TimeLeave, value);
        }

        private string _TaskCount;

        public string TaskCount
        {
            get => _TaskCount;
            set => SetProperty(ref _TaskCount, value);
        }
        private string CurrentFile;

        private ICommand _AjustOneCommand;
        private ICommand _OpenFileCommand;
        private ICommand _AjustAllCommand;
        private ICommand _FileClickCommand;
        private ICommand _ClearListCommand;

        public ICommand AjustOneCommand =>
            _AjustOneCommand
            ?? (
                _AjustOneCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                    {
                        return;
                    }
                    CurrentFile = (string)o;
                    if (!File.Exists(CurrentFile))
                    {
                        var content = new NotificationContent()
                        {
                            Title = "字幕文件不存在",
                            Type = NotificationType.Warning,
                            Message = CurrentFile,
                        };
                        AppManager.Instance.NotificationManager.Show(content);
                        return;
                    }
                    SubtitleList.Clear();
                    string offsetString = TimeLeave;
                    if (string.IsNullOrEmpty(offsetString))
                    {
                        var content = new NotificationContent()
                        {
                            Title = "请输入时间偏移量",
                            Type = NotificationType.Error
                        };
                        AppManager.Instance.NotificationManager.Show(content);
                        return;
                    }
                    List<Subtitle> subtitles = SubtitleUtils.ReadSubtitle(CurrentFile);

                    AjustAllEnable = false;
                    AjustOneEnable = false;
                    ClearListEnable = false;

                    TimeSpan offset = TimeSpan.Parse("00:00:00");
                    bool add = true;
                    offsetString = offsetString.Replace("：", ":");
                    if (offsetString.StartsWith("-"))
                    {
                        add = false;
                        offsetString = offsetString.Substring(1);
                    }
                    try
                    {
                        offset = TimeSpan.Parse(offsetString);
                    }
                    catch (Exception ex)
                    {
                        var content = new NotificationContent()
                        {
                            Title = "时间偏移量格式错误",
                            Type = NotificationType.Error,
                            Message = "格式(减号开始表示时间前移)\n(-)00:00:00",
                        };
                        AppManager.Instance.NotificationManager.Show(content);
                        return;
                    }
                    System.Threading.Tasks.Task.Run(() =>
                    {
                        int count = subtitles.Count();
                        StringBuilder content = new StringBuilder();
                        int index = 1;
                        for (int i = 0; i < count; i++)
                        {
                            Subtitle subtitle = subtitles[i];
                            bool escape = false;
                            if (add)
                            {
                                subtitle.StartTime = subtitle.StartTime.Add(offset);
                            }
                            else
                            {
                                TimeSpan start = subtitle.StartTime;
                                double oldTotal = start.TotalMilliseconds;
                                if (oldTotal < offset.TotalMilliseconds)
                                {
                                    escape = true;
                                }
                                subtitle.StartTime = subtitle.StartTime.Subtract(offset);
                            }

                            if (add)
                            {
                                subtitle.EndTime = subtitle.EndTime.Add(offset);
                            }
                            else
                            {
                                TimeSpan end = subtitle.EndTime;
                                double oldTotal = end.TotalMilliseconds;
                                if (oldTotal < offset.TotalMilliseconds)
                                {
                                    escape = true;
                                }
                                subtitle.EndTime = subtitle.EndTime.Subtract(offset);
                            }
                            if (!escape)
                            {
                                if (subtitle.Text.Trim().Length != 0)
                                {
                                    subtitle.Number = index;
                                    content.Append(subtitle.ToString()).Append("\n");
                                    index++;
                                }
                            }
                        }
                        //Log.Information(content.ToString());
                        string saveFile = CurrentFile.Replace(".srt", "_out.srt");
                        if (TradToSimple)
                        {
                            System.IO.File.WriteAllText(
                                saveFile,
                                ChineseConverter.Convert(content.ToString(),ChineseConversionDirection.TraditionalToSimplified),
                                Encoding.UTF8
                            );
                        }
                        else
                        {
                            System.IO.File.WriteAllText(
                                saveFile,
                                content.ToString(),
                                Encoding.UTF8
                            );
                        }

                        AjustAllEnable = true;
                        AjustOneEnable = true;
                        ClearListEnable = true;
                    });
                })
            );
        public ICommand OpenFileCommand =>
            _OpenFileCommand
            ?? (
                _OpenFileCommand = new RelayCommand<object>(o =>
                {
                    FileList.Clear();
                    System.Windows.Forms.OpenFileDialog openFileDialog =
                        new System.Windows.Forms.OpenFileDialog();
                    string filter = "srt字幕文件(*.srt)|*.srt";
                    openFileDialog.Filter = filter;
                    openFileDialog.Multiselect = true;
                    openFileDialog.RestoreDirectory = true;
                    openFileDialog.FilterIndex = 1;
                    if (openFileDialog.ShowDialog() == DialogResult.OK)
                    {
                        foreach (var f in openFileDialog.FileNames)
                        {
                            FileList.Add(f);
                        }

                        AjustAllEnable = true;
                        AjustOneEnable = true;
                        ClearListEnable = true;
                        TaskCount = "任务数量：" + FileList.Count;
                    }
                    else
                    {
                        return;
                    }
                })
            );
        public ICommand AjustAllCommand =>
            _AjustAllCommand
            ?? (
                _AjustAllCommand = new RelayCommand<object>(o =>
                {
                    TimeSpan offset = TimeSpan.Parse("00:00:00");
                    bool add = true;
                    string offsetString = TimeLeave;
                    if (string.IsNullOrEmpty(offsetString))
                    {
                        var content = new NotificationContent()
                        {
                            Title = "请输入时间偏移量",
                            Type = NotificationType.Error
                        };
                        AppManager.Instance.NotificationManager.Show(content);
                        return;
                    }

                    AjustAllEnable = false;
                    AjustOneEnable = false;
                    ClearListEnable = false;

                    offsetString = offsetString.Replace("：", ":");
                    if (offsetString.StartsWith("-"))
                    {
                        add = false;
                        offsetString = offsetString.Substring(1);
                    }
                    try
                    {
                        offset = TimeSpan.Parse(offsetString);
                    }
                    catch
                    {
                        var content = new NotificationContent()
                        {
                            Title = "时间偏移量格式错误",
                            Type = NotificationType.Error,
                            Message = "开始时间结束时间偏移量\n格式(减号开始表示时间前移)\n(-)00:00:00"
                        };
                        AppManager.Instance.NotificationManager.Show(content);
                        return;
                    }
                    if (FileList.Count > 0)
                    {
                        AjustAllEnable = false;
                        AjustOneEnable = false;
                        ClearListEnable = false;
                        System.Threading.Tasks.Task.Run(() =>
                        {
                            for (int j = 0; j < FileList.Count; j++)
                            {
                                int index = 1;
                                var log = new StringBuilder();
                                string file = FileList[j];
                                List<Subtitle> subtitles = SubtitleUtils.ReadSubtitle(file);
                                if (subtitles.Count == 0)
                                {
                                    var contentb = new NotificationContent()
                                    {
                                        Title = "字幕为空",
                                        Type = NotificationType.Error,
                                        Message = file
                                    };
                                    AppManager.Instance.NotificationManager.Show(contentb);
                                    continue;
                                }

                                int count = subtitles.Count();
                                StringBuilder content = new StringBuilder();
                                for (int i = 0; i < count; i++)
                                {
                                    bool escape = false;
                                    Subtitle subtitle = subtitles[i];
                                    if (add)
                                    {
                                        subtitle.StartTime = subtitle.StartTime.Add(offset);
                                    }
                                    else
                                    {
                                        TimeSpan start = subtitle.StartTime;
                                        double oldTotal = start.TotalMilliseconds;
                                        if (oldTotal < offset.TotalMilliseconds)
                                        {
                                            escape = true;
                                        }
                                        subtitle.StartTime = subtitle.StartTime.Subtract(offset);
                                    }

                                    if (add)
                                    {
                                        subtitle.EndTime = subtitle.EndTime.Add(offset);
                                    }
                                    else
                                    {
                                        TimeSpan end = subtitle.EndTime;
                                        double oldTotal = end.TotalMilliseconds;
                                        if (oldTotal < offset.TotalMilliseconds)
                                        {
                                            escape = true;
                                        }
                                        subtitle.EndTime = subtitle.EndTime.Subtract(offset);
                                    }
                                    if (!escape)
                                    {
                                        if (subtitle.Text.Trim().Length != 0)
                                        {
                                            subtitle.Number = index;
                                            content.Append(subtitle.ToString()).Append("\n");
                                            index++;
                                        }
                                    }
                                }
                                string saveFile = file.Replace(".srt", "_out.srt");
                                if (TradToSimple)
                                {
                                    System.IO.File.WriteAllText(
                                        saveFile,
                                        ChineseConverter.Convert(content.ToString(), ChineseConversionDirection.TraditionalToSimplified),
                                        Encoding.UTF8
                                    );
                                }
                                else
                                {
                                    System.IO.File.WriteAllText(
                                        saveFile,
                                        content.ToString(),
                                        Encoding.UTF8
                                    );
                                }
                                TaskCount = "完成任务数量：" + (j + 1);
                            }

                            AjustAllEnable = true;
                            AjustOneEnable = true;
                            ClearListEnable = true;
                        });
                    }
                })
            );
        public ICommand FileClickCommand =>
            _FileClickCommand
            ?? (
                _FileClickCommand = new RelayCommand<object>(o =>
                {
                    if (o == null)
                    {
                        return;
                    }
                    CurrentFile = (string)o;
                    if (!File.Exists(CurrentFile))
                    {
                        var content = new NotificationContent()
                        {
                            Title = "字幕文件不存在",
                            Type = NotificationType.Error,
                            Message = CurrentFile
                        };
                        AppManager.Instance.NotificationManager.Show(content);
                        return;
                    }
                    SubtitleList.Clear();
                    List<Subtitle> subtitles = SubtitleUtils.ReadSubtitle(CurrentFile);
                    foreach (Subtitle sub in subtitles)
                    {
                        SubtitleList.Add(sub);
                    }
                })
            );
        public ICommand ClearListCommand =>
            _ClearListCommand
            ?? (
                _ClearListCommand = new RelayCommand<object>(o =>
                {
                    FileList.Clear();
                    SubtitleList.Clear();
                    TaskCount = "";
                    AjustAllEnable = false;
                    AjustOneEnable = false;
                    ClearListEnable = true;
                })
            );
    }
}
